package com.abl.common.util;

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.Status;
import org.ehcache.UserManagedCache;
import org.ehcache.config.builders.*;
import org.ehcache.config.units.MemoryUnit;

import java.time.Duration;

public class EhcacheKit {
    /**
     * 此对象在项目启动时就已经完成初始化了
     * 直接使用 EhcacheKit.instance()  即可
     */
    public static UserManagedCache<String, Object> userManagedCache = UserManagedCacheBuilder.newUserManagedCacheBuilder(String.class, Object.class).build(false);
    // preConfigured：缓存的名称，可以创建多个，可以对每个缓存进行不同的设置。比方说对A缓存设置过期时间，B缓存不设置过期时间。
    //    String.class，ResponseObject.class：你可以理解为是key是String类型的，value是ResponseObject类型的。
    //    等会获取缓存是根据String类型key来获取ResponseObject类型的value的。
    //    heap(1000L)：代表preConfigured下的缓存最多存1000个key，如果是1001则把第一个缓存删除。
    //    当然也可以设置offHeap()这个代表如果超过heap()设置的缓存数，则把缓存存到offHeap()设置的磁盘上。（本次没用）
    //    withExpiry：对preConfigured下的缓存设置超时时间（上面的例子是20秒自动过期），EhCache的缓存过期机制有3种，想了解的可以去官网。 


    /**
     * 返回 永久储存的缓存对象
     */
    public static Cache<String, Object> instance() {
        if (userManagedCache.getStatus().equals(Status.UNINITIALIZED)) {
            synchronized (Object.class) {
                if (userManagedCache.getStatus().equals(Status.UNINITIALIZED)) {
                    userManagedCache.init();
                }
            }
        }
        return userManagedCache;
    }

    /**
     * 返回 会失效的 缓存对象
     * <p>
     * 默认 1000条 和 100M堆外缓存
     *
     * @param seconds 缓存失效时间,单位秒
     * @throws ：试图分配超出JVM允许范围的堆外内存。堆外内存大小的限制由-XX：MaxDirectMemorySize命令（或等效命令）
     */

    public static Cache<String, Object> instance(long seconds) {
        return instance(seconds, 1000, 100);
    }


    /**
     * 返回 会失效的 缓存对象
     *
     * @param seconds 缓存失效时间,单位秒
     * @param heap    JVM可以存放的条数
     * @param offHeap 堆外内存MB,(普通上限大约4000M)，将你的对象从堆中脱离出来，存储在一大块内存中，仍然在RAM(随机存储器，程序运行所占内存)中
     *                不受垃圾收集。堆外内存能够降低GC导致的暂停。
     * @throws ：试图分配超出JVM允许范围的堆外内存。堆外内存大小的限制由-XX：MaxDirectMemorySize命令（或等效命令）
     */
    public static Cache<String, Object> instance(long seconds, long heap, long offHeap) {
        CacheManager cacheManager =
                CacheManagerBuilder.newCacheManagerBuilder()
                        .withCache(
                                "EhcacheKit-instance-time" + seconds,
                                CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, ResourcePoolsBuilder.heap(heap).offheap(offHeap, MemoryUnit.MB)).withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(seconds)))
                        ).build();
        cacheManager.init();
        return cacheManager.getCache("EhcacheKit-instance-time" + seconds, String.class, Object.class);
    }

//        PersistentCacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
//                .with(CacheManagerBuilder.persistence("C:\\Users\\Administrator\\Desktop\\cache"))
//                //持久化硬盘路径
//                .withCache("sharedCache",
//                        CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class,
//                                ResourcePoolsBuilder.newResourcePoolsBuilder()
//                                        .heap(1, EntryUnit.ENTRIES)//缓存的单位个数  也可设 KB、MB、GB，
//                                        .heap(40, MemoryUnit.MB)
//                                        .offheap(50, MemoryUnit.MB) //堆外
//                                        .disk(10, MemoryUnit.GB, true))) //硬盘，第三个boolean参数设置是否持久化
//                .build(true);//创建并初始化

    //整数字符串缓存配置生成器
//        CacheConfigurationBuilder<String, String> configurationBuilder =
//                CacheConfigurationBuilder.newCacheConfigurationBuilder(
//                        String.class,
//                        String.class,
//                        ResourcePoolsBuilder.newResourcePoolsBuilder()
//                                .heap(1000, EntryUnit.ENTRIES)  //堆
//                                .offheap(200, MemoryUnit.MB)    //堆外
//                                .disk(2, MemoryUnit.GB)      //磁盘
//                );
//
//        //持久性缓存管理器
//        PersistentCacheManager persistentCacheManager =
//                CacheManagerBuilder
//                        .newCacheManagerBuilder()
//                        .with(CacheManagerBuilder.persistence("C:\\Users\\Administrator\\Desktop\\cache"))
//                        .withCache("sharedCache", configurationBuilder)
//                        .build(true);
//
////        Cache<String, String> cache = persistentCacheManager.getCache("sharedCache", String.class, String.class);
////        Cache<String, String> cache = cacheManager.getCache("sharedCache", String.class, String.class);
//
//
//        //读
//        for (int i = 0; i <= 10; i++) {
//            Object o = cache.get(i + "");
//            System.out.println(i + "=" + o);
//        }
//
//        //写
//        for (int i = 0; i <= 10; i++) {
//            cache.put(i + "", "$" + i);
//        }
//
//        //读
//        for (int i = 0; i <= 10; i++) {
//            Object o = cache.get(i + "");
//            System.out.println(i + "=" + o);
//        }
//        Thread.sleep(10000 * 1000);
//    }
}
